-
Notifications
You must be signed in to change notification settings - Fork 8.2k
net: ping: Improve the output of the ping function #14024
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
All checks are passing now. Review history of this comment for details about previous failed status. |
Codecov Report
@@ Coverage Diff @@
## master #14024 +/- ##
==========================================
- Coverage 52.68% 52.6% -0.08%
==========================================
Files 307 307
Lines 45473 45474 +1
Branches 10530 10530
==========================================
- Hits 23956 23923 -33
- Misses 16640 16668 +28
- Partials 4877 4883 +6
Continue to review full report at Codecov.
|
ad5ff11 to
53fd7d1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That looks very nice features, thanks!
But there're thing to elaborate in the patch still.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @benpicco, this looks really nice. Just few fixes and we are good to go.
7bd6c57 to
0481440
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Split the 2nd commit in 3:
- one adding timestamp as arbitrary data for icmpv4
- one adding timestamp as arbitrary data for icmpv6
- one improving shell
and apply all the comments as well.
subsys/net/ip/icmpv4.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
where in icmpv4 rfc did you see such field for echo request?
That structure represents the echo req as specified from the RFC so you cannot modify it.
if you want to add data past the echo_req id/seq, you'll have to do it another way.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea you are right. I've changed it to a u8_t data[] and let the application decide what arbitrary payload to put in there (if any).
subsys/net/ip/icmpv6.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not RFC compliant
subsys/net/ip/net_shell.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
use net_pkt_ieee802154_rssi() (btw, rssi for 15.4 is u8_t as it is a value between 0 and 255, why the cast?)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The data coming from the nrf52 is a s8_t tough, and RSSI is usually given in negative dBm.
The only other use is currently in openthread.c where it is implicitly cast to s8_t again.
I think this is a bug in Zephyr's ieee802154 API.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
zephyr's 15.4 stack implements rssi as specified in 15.4 specs (8bits value from 0 to 255).
Ref: spec 2012 chapter 18.2.3.3
Though dbm would be indeed better (as it is the scale used also in BT and WiFi). I don't know why 15.4 came with its own definition.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, with two's complement it doesn't make a difference either way, higher values are better no matter if they are interpreted as signed or not.
If the standard says so I'll remove the cast.
|
@benpicco, Thanks for addressing the initial concerns raised. |
9391958 to
e72271b
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 for doc change
46b57d0 to
c70e631
Compare
subsys/net/ip/icmpv6.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
80 chars limit is passed here I guess
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved it to the next line
subsys/net/ip/net_shell.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a bit problematic, because the target (if implementing reply wrongly) might have replied without the arbitrary data (it is against RFC but there is no way to verify this until you actually reach this cb).
Instead just use net_pkt_read_be32_new(), that will tell you if there is an error, in which case you will return NET_DROP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, changed it to use net_pkt_read_be32_new() instead.
subsys/net/ip/icmpv4.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So that won't be necessary then
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
subsys/net/ip/icmpv4.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though, at this stage of this function implementation, this logic is not wrong, it won't fly with time if one day the icmpv4_access is not a contiguous one anymore.
And in any case, never memcpy (or memmove etc..) by yourself. Alway use the net_pkt r/w api, because that API can tell you if it could r/w or not (it verifies that buffer does have the necessary space)
So after net_pkt_set_data() below, just do a net_pkt_write(pkt, data, data_size)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, changed it to net_pkt_write_new().
subsys/net/ip/icmpv6.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
apply the same as for icmpv4.c
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
subsys/net/ip/icmpv4.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
80 chars limit
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
moved it to the next line
|
I guess you need to rebase and actually apply the fixups (git rebase -i for interactive mode) |
|
I know, just thought it makes reviewing easier this way. |
Allow for including arbitrary data in net_icmpv4_send_echo_request() that will be echoed verbatim by the receiver. This allows to use ICMP echo for diagnostic use cases, e.g. by testing packet framentation (large payload) or measuring round-trip-time. Signed-off-by: Benjamin Valentin <[email protected]>
Allow for including arbitrary data in net_icmpv6_send_echo_request() that will be echoed verbatim by the receiver. This allows to use ICMP echo for diagnostic use cases, e.g. by testing packet framentation (large payload) or measuring round-trip-time. Signed-off-by: Benjamin Valentin <[email protected]>
164d1ab to
5239d05
Compare
|
Could you please add size parameter? |
|
@bublover Good idea, added it. I'm not so happy about the VLA use, but I've only tested the IPv6 version, but IPv4 should work the same. |
subsys/net/ip/net_shell.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi @benpicco ,
About this payload, is it allocated from heap or thread stack or something else?
If from thread stack, is it possible to be overflowed with big size?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using VLAs is no good, please do it differently. One option could be to allocate enough net_buf's for a given size, and then pass that chain of net_buf's directly to net_icmpv6_send_echo_request() which can then send that data directly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it's allocated on the stack and yes that's bad.
I'm not sure how to do it with net_bufs though. Is there a way where I don't have to reserve dedicated memory for it using NET_BUF_POOL_DEFINE but instead can make use of some existing pool?
Another way would be to only enable the -s option if CONFIG_HEAP_MEM_POOL_SIZE is not 0.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, we seem to have lost proper API in net_pkt.h for allocating net_buf's.
Another option could be to use net_pkt_skip() and optionally with net_pkt_memset(). That way we could fill enough net_buf's with given byte value. This would be needed to be done inside net_icmpv6_send_echo_request() as the net_pkt is not exposed outside of that function.
So for example we could have something like net_icmpv6_send_echo_request(iface, dst, id, seq, len, value), and inside that func just do net_pkt_skip(pkt, len) followed by cursor setting and then net_pkt_memset(pkt, value). The cursor setting is a bit vague here as I am just brainstorming atm.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After looking how net_pkt_skip() and net_pkt_memset() are implemented, it is probably enough just to call net_pkt_memset() which should allocate enough net_buf's to fill the packet.
subsys/net/ip/net_shell.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using VLAs is no good, please do it differently. One option could be to allocate enough net_buf's for a given size, and then pass that chain of net_buf's directly to net_icmpv6_send_echo_request() which can then send that data directly.
|
@benpicco could you rebase against latest master and re-submit without the size support, we can add that one later in separate PR. |
|
@jukkar alright! |
subsys/net/ip/net_shell.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Print float data depends on some additional configs, otherwise, the time can not output correctly.
28 bytes from 192.168.1.1 to 192.168.1.100: icmp_seq=1 ttl=64 time=%.2f ms
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suppose it's CONFIG_NEWLIB_LIBC_FLOAT_PRINTF and it only affects the formatting to two significant digits as %f is used elsewhere in that file.
Does it work for you now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It also doesn't work with %f, can you please use %d instead as this is a universal network tool.
28 bytes from 192.168.1.1 to 192.168.1.100: icmp_seq=0 ttl=64 time=%f ms
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What target / config are you using?
When I build for nrf52840_pca10056, CONFIG_NEWLIB_LIBC_FLOAT_PRINTF is not set, yet %.2f is available.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@benpicco I'm using 96boards IVY5661, the board support patch(#10626) is not merged yet.
I tried to store time in a variable before output, It's very strange that printf works, but PR_SHELL not. It seems there is some issue with PR_SHELL.
float time;
time = SYS_CLOCK_HW_CYCLES_TO_NS(cycles) / 1000000.f;
printf("time: %f.\n", time);
PR_SHELL(shell_for_ping, "%d bytes from %s to %s: icmp_seq=%d ttl=%d time=%f ms\n",
ntohs(ip_hdr->len) - net_pkt_ipv6_ext_len(pkt) - NET_ICMPH_LEN,
net_sprint_ipv4_addr(&ip_hdr->src),
net_sprint_ipv4_addr(&ip_hdr->dst),
ntohs(icmp_echo->sequence),
ip_hdr->ttl,
time);
OUTPUT:
time: 4.418798.
28 bytes from 192.168.1.1 to 192.168.1.101: icmp_seq=0 ttl=64 time=%f ms
subsys/net/ip/net_shell.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this and noticed some issues. Using atoi() is not good as it returns 0 for invalid value. That is why the net-shell uses strtol() in other parts of the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, converted it to use strtol()
subsys/net/ip/net_shell.c
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just noticed that we cannot stop the ping after it is started. So if the user puts very high value here, the shell will be useless for a long period of time. I wonder if we could run the ping in separate thread or something like that in order to avoid this thing. We can do some limits later, no need to start to implement something like that here.
|
We have now another problem. When compiling After enabling You need to add () when dividing like this For the float issue, add this change |
So, I'd say we should keep avoiding floating point like we did before, and use fixed points calculations. |
|
I've changed it so that it only uses float when @easonxiang does this also remedy the problem on uwp5661? |
@benpicco Yes, the int type works for me. I can not enable CONFIG_FLOAT as it depends on CPU_HAS_FPU, which is not available by uwp5661. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are almost there, just one tweak needed.
Report rtt, ttl and rssi if available. Signed-off-by: Benjamin Valentin <[email protected]>
The output of the
net pingfunction is a bit terse.Let's make it more Linux-like by reporting TTL, measuring round-trip-time and also display RSSI when available.
before:
after: